import axios from 'axios'
import Storage from './storage-helper';
import CryptoHelper from './cryptoJs-helper';

const CANCELTTYPE = {
  CACHE: 1,
  REPEAT: 2,
};

// 创建一个axios实例
const http = axios.create();
const storage = new Storage();
const cryptoHelper = new CryptoHelper('cacheKey');

const pendingRequests = [];

// 请求的拦截器
http.interceptors.request.use(config => {
  // 为每一次请求生成一个cancleToken
  const source = axios.CancelToken.source()
  config.cancelToken = source.token
  // 缓存的判断；
  const data = storage.get(cryptoHelper.encrypt(config.url + JSON.stringify(config.data) + (config.methos || '')))

  if (data && (Date.now() <= data.exppries)) {
    console.log(`接口：${config.url} 缓存命中 -- ${Date.now()} -- ${data.exppries}`);
    source.cancel(JSON.stringify({
      type: CANCELTTYPE.CACHE,
      data: data.data,
    }))
  }

  // 判断重复请求 同url，同请求类型判定为重复请求
  const md5Key = cryptoHelper.encrypt(config.url + (config.method || ''));
  const hits = pendingRequests.filter((item) => item.md5Key === md5Key);
  if (hits.length > 0) {
    hits.forEach((item) => item.source.cancel(JSON.stringify({
      type: CANCELTTYPE.REPEAT,
      data: '重复请求，以取消',
    })));
  }

  // 将当前请求添加进请求对列中
  pendingRequests.push({
    md5Key,
    source,
  });

  return config;

})

// 处理响应的拦截器
http.interceptors.response.use(res => {
  // 不论请求是否成功，将本次完成的请求从请求队列中移除
  const md5Key = cryptoHelper.encrypt(res.config.url + (res.config.method || ''));
  const index = pendingRequests.findIndex((item) => item.md5Key === md5Key);
  if (index > -1) {
    pendingRequests.splice(index, 1);
  }
  if (res.data) {
    if (res.config.data) {
      const dataParse = JSON.parse(res.config.data);
      if (dataParse.cache) {
        if (!dataParse.cacheTime) {
          dataParse.cacheTime = 1000 * 60 * 3;
        }
        storage.set(cryptoHelper.encrypt(res.config.url + res.config.data + (res.config.method || '')), {
          data: res.data.data,
          exppries: Date.now() + dataParse.cacheTime,
        });
        console.log(`接口：${res.config.url} 设置缓存，缓存时间: ${dataParse.cacheTime}`);
      }
    }
    return res.data;
  } else {
    return Promise.reject('接口报错了！');
  }

})

// const httpHelper = {
//   get(url, params) {
//     return new Promise((resolve, reject) => {
//       http.get(url, params).then(async (res) => {
//         resolve(res);
//       }).catch((error) => {
//         if (axios.isCancel(error)) {
//           const cancle = JSON.parse(error.message);
//           if (cancle.type === CANCELTTYPE.REPEAT) {
//             return resolve([]);
//           } else {
//             return resolve(cancle.data);
//           }
//         } else {
//           return reject(error);
//         }
//       });
//     });
//   },
//   post(url, params) {
//     return new Promise((resolve, reject) => {
//       http.post(url, params).then(async (res) => {
//         resolve(res);
//       }).catch((error) => {
//         if (axios.isCancel(error)) {
//           const cancle = JSON.parse(error.message);
//           if (cancle.type === CANCELTTYPE.REPEAT) {
//             return resolve(null);
//           } else {
//             return resolve(cancle.data);
//           }
//         } else {
//           return reject(error);
//         }
//       });
//     });
//   },
// };

export default http